#pragma once 
#include<iostream>
#include<assert.h>
#include<vector>
using namespace std;
namespace hcc
{
    template <class T>
    class vector
    {
        public:
            typedef T* iterator;
            typedef const T* const_iterator;
            void swap(vector& d)
            {
                std::swap(_start,d._start);
                std::swap(_finish,d._finish);
                std::swap(_end_of_storage,d._end_of_storage);
            }
            vector()
                :_start(nullptr)
                ,_finish(nullptr)
                ,_end_of_storage(nullptr)
            {}
            template<class inputiterator>
            vector(inputiterator first,inputiterator last)
                    :_start(nullptr)
                    ,_finish(nullptr)
                    ,_end_of_storage(nullptr)
            {
                while(first!=last)
                {
                    push_back(*first);
                    first++;
                }
            }
            vector(const vector<T>& d)
                :_start(nullptr)
                ,_finish(nullptr)
                ,_end_of_storage(nullptr)
            {
                vector<T> tem(d.begin(),d.end());
                swap(tem);
            }
            ~vector()
            {
                delete[] _start;
                _start=_finish=_end_of_storage=nullptr;
            }
            vector<T>& operator=(vector<T> d)
            {
                swap(d);
                return *this;
            }
            T& operator[](size_t x)
            {
                return _start[x];
            }
            const T& operator[](size_t x) const
            {
                return _start[x];
            }
            size_t size() const
            {
                return _finish-_start;
            }
            iterator begin() 
            {
                return _start;
            }
            iterator end()
            {
                return _finish;
            }
            const_iterator begin() const 
            {
                return _start;
            }
            const_iterator end() const 
            {
                return _finish;
            }
            size_t capacity()
            {
                return _end_of_storage-_start;
            }
            void reserve(size_t n)
            {
                if(n>capacity())
                {
                    size_t sz=_finish-_start;
                    T* tem=new T[n];
                    for(size_t i=0;i<size();i++)
                    {
                        tem[i]=_start[i];
                    }
                    delete[] _start;
                    _start=tem;
                    _finish=_start+sz;
                    _end_of_storage=_start+n;
                }
            }
            void push_back(const T& x)
            {
                if(_start==_end_of_storage)
                    reserve(4);
                if(_end_of_storage==_finish)
                    reserve(2*capacity());
                _start[size()]=x;
                _finish++;
            }
            void resize(size_t n,const T& x=T())
            {
                if(n>capacity())
                    reserve(n);
                if(n<size())
                {
                    _finish=_start+n;
                }
                if(n>size()&&n<=capacity())
                {
                    size_t ret=n-size();
                    for(size_t i=0;i<ret;i++)
                    {
                        _start[i]=x;
                    }
                    _finish=_start+n;
                }
            }
            T& front()
            {
                return _start[0];
            }
            T& back()
            {
                return _start[size()-1];
            }
        private: 
            iterator _start;
            iterator _finish;
            iterator _end_of_storage;

    };
}
